package controller;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import javax.persistence.TypedQuery;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import restaurant.MenuCategory;
import restaurant.MenuItem;

/**
 * Servlet implementation class Menu
 */
@WebServlet("/Menu")
public class Menu extends HttpServlet {
    private static final long serialVersionUID = 201211021341L;

    protected final Map<String, List<MenuItem>> menuItemsByCategory = new LinkedHashMap<>();
    protected final Map<String, String> tagIcons = new TreeMap<>();

    protected EntityManagerFactory _emf;

    private static String UNIT_NAME = "ThaiKitchen";

    @Override
    public void init(final ServletConfig config) throws ServletException {
        super.init(config);
        config.getServletContext().log("Initializing persistence unit [" + UNIT_NAME + "]");
        try {
            _emf = Persistence.createEntityManagerFactory(UNIT_NAME);
        } catch (Exception e) {
            throw new ServletException(e);
        }
        config.getServletContext().log("Initialized with persistence unit [" + UNIT_NAME + "]");

        tagIcons.put("special",    "images/icons/star.png");
        tagIcons.put("spicy",      "images/icons/fire.png");
        tagIcons.put("vegetarian", "images/icons/leaf.png");
    }

    /**
     * Sort first by number (should be unique, but just in case...), then by name, then by modifier, then give preference to
     * {@link MenuItem a}.
     *
     * @author larsonmp
     */
    protected static class MenuSorter implements Comparator<MenuItem> {
        @Override
        public int compare(final MenuItem a, final MenuItem b) {
            if (!a.getNumber().equals(b.getNumber())) {
                return a.getNumber().compareTo(b.getNumber());
            } else if (!a.getName().equals(b.getName())) {
                return a.getName().compareTo(b.getName());
            } else if(!a.getModifier().equals(b.getModifier())) {
                return a.getModifier().compareTo(b.getModifier());
            } else {
                return -1;
            }
        }
    }

    @Override
    protected void doGet(final HttpServletRequest req, final HttpServletResponse response) throws ServletException, IOException {
        final String id = req.getParameter("id");
        req.setAttribute("id", id);

        final EntityManager em = _emf.createEntityManager();
        final TypedQuery<MenuCategory> q = em.createQuery("select c from MenuCategory c", MenuCategory.class);
        final List<MenuCategory> categories = q.getResultList();

        req.setAttribute("categories", categories);

        for (final MenuCategory category : categories) {
            final List<MenuItem> menuItems = new ArrayList<>();
            TypedQuery<MenuItem> q2 = em.createQuery("select m from MenuItem m where m.category = :category", MenuItem.class);
            q2.setParameter("category", category);
            menuItems.addAll(q2.getResultList());
            Collections.sort(menuItems, new MenuSorter());

            menuItemsByCategory.put(category.getName(), menuItems);
        }

        req.setAttribute("menuItemsByCategory", menuItemsByCategory);

        req.setAttribute("tagIcons", tagIcons);

        req.setAttribute("namesToPages", getLinkMap());
        req.getRequestDispatcher(getDispatcherPage()).forward(req, response);
        em.close();
    }

    protected Map<String, String> getLinkMap() {
        return LinkData.getLinkMap();
    }

    protected String getDispatcherPage() {
        return "/WEB-INF/menu.jsp";
    }
}
